---------------------------------------------------------------------------------
  -- Design Name : Instruction Fetch Stage
  -- File Name   : if.vhd
  -- Function    : Instruction fetch stage
  -- Authors     : Mirko Francuski  2006/0225
  --               Milos Mihajlovic 2006/0039
  -- School      : University of Belgrade
  --               School for Electrical Engineering
  --               Department for Computer Engineering and Information Theory
  -- Subject     : VLSI Computer Systems
---------------------------------------------------------------------------------

library ieee;

use ieee.std_logic_1164.all;
use ieee.std_logic_signed.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
use work.UserPkg.all;

entity IfStage is
  port (
    clk         : in  std_logic;
    wrkIn       : in  std_logic;
    wrkOut      : out std_logic;
    branchTaken : in  std_logic;
    loRTS       : in  std_logic;
    stall       : in  std_logic;
    reset       : in  std_logic;
    newAddr     : in  word32;
    wbOut       : in  word32;
    newPC       : out word32 := (others => '0');
    aiBusReq    : out std_logic;
    aiBUS       : out word32 := (others => 'Z')
  );
end IfStage;

architecture behavioral of IfStage is
  signal addV :         std_logic;
  signal addC :         std_logic;
  signal clock :        std_logic;
  signal pcOut :        word32;
  signal pcMUXOut :     word32;
  signal postPCMUXOut : word32;
  signal addOut :       word32;
  signal four :         word32;
  signal PCld :         std_logic;
begin
  
  aiBusReq <= wrkIn;
  aiBUS <= postPCMUXOut;
  
  newPC <= addOut;
  clock <= clk and wrkIn;
  wrkOut <= wrkIn;
  
  PCld  <= wrkIn;
 
  pcMUX: GenMux32_2 port map (
    in1    => addOut,
    in2    => wbOut,
    sel    => loRTS,
    muxOut => pcMUXOut
  );
  
  postPCMUX: GenMux32_2 port map (
    in1    => pcOut,
    in2    => newAddr,
    sel    => branchTaken,
    muxOut => postPCMUXOut
  );
  
  pc: GenRegExt32 port map ( 
    clk    => clock,
    ld     => PCld,
    cl     => reset,
    inc    => '0',
    dec    => stall,
    regIn  => pcMUXOut,
    regOut => pcOut
  );
  
  four <= (0 => '1', others => '0'); --number 1
  
  adder: GenAdd32 port map ( 
    in1     => four,
    in2     => postPCMUXOut,
    add_out => addOut,
    v       => addV,
    c       => addC
  );
  
  process(addV, addC)
  begin
    if addV  or addC then
      report "Interrupt: PC address overflow." severity failure;
    end if;
  end process;
  
end architecture behavioral;